// Created: Dec 14, 2014
//
// Author: wjinwen.1988@gmail.com

#include "chi/net/event_loop_thread_pool.h"
#include "chi/net/event_loop.h"
#include "chi/net/event_loop_thread.h"

namespace chi {
namespace net {

EventLoopThreadPool::EventLoopThreadPool(EventLoop* base_loop) 
  : base_loop_(base_loop),
    started_(false),
    num_threads_(0),
    next_(0) {
}

EventLoopThreadPool::~EventLoopThreadPool() {
  // Don't delete loop, it's stack variable.

  for (auto& it : threads_) {
    EventLoopThread* thread = it;
    thread->StopLoop();
    delete thread;
  }
}

void EventLoopThreadPool::Start(const ThreadInitCallback& cb) {
  assert(!started_);
  
  started_ = true;

  for (int i = 0; i < num_threads_; ++i) {
    EventLoopThread* t = new EventLoopThread(cb);
    threads_.push_back(t);
    loops_.push_back(t->StartLoop());
  }

  if (num_threads_ == 0 && cb) {
    cb(base_loop_);
  }
}

EventLoop* EventLoopThreadPool::GetNextLoop() {
  EventLoop* loop = base_loop_;

  if (!loops_.empty()) {
    // round-robin
    loop = loops_[next_];
    ++next_;
    if (static_cast<size_t>(next_) >= loops_.size()) {
      next_ = 0;
    }
  }
  return loop;
}

} 
}
